package com.xj.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xj.reggie.common.R;
import com.xj.reggie.dto.DishDto;
import com.xj.reggie.entity.*;
import com.xj.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author XJ
 * @Date 2022/10/19 15:30
 * @PackageName:com.xj.reggie.controller
 * @ClassName: DishController
 * @Description: 菜品管理
 * @Version 1.0
 */
@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {

	@Autowired
	private DishService dishService;

	@Autowired
	private DishFlavorService dishFlavorService;

	@Autowired
	private CategoryService categoryService;

	@Autowired
	private SetmealService setmealService;

	@Autowired
	private SetmealDishService setmealDishService;

	/**
	 * 新增菜品
	 * @param dishDto
	 * @return
	 */
	@PostMapping
	private R<String> save(@RequestBody DishDto dishDto){
		log.info(dishDto.toString());

		dishService.saveWithFlavor(dishDto);

		return R.success("新增菜品成功！");
	}

	/**
	 * 菜品信息分页查询
	 * @param page
	 * @param pageSize
	 * @param name
	 * @return
	 */
	@GetMapping("/page")
	public R<Page> page(int page,int pageSize,String name){

		//构造分页构造对象
		Page<Dish> pageInfo = new Page<>(page,pageSize);
		Page<DishDto> dishDtoPage = new Page<>();

		//条件构造器
		LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
		//添加过滤条件
		queryWrapper.like(name !=null,Dish::getName,name);
		//添加排序条件
		queryWrapper.orderByDesc(Dish::getUpdateTime);

		//执行分页查询
		dishService.page(pageInfo,queryWrapper);

		//对象拷贝
		BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");


		List<Dish> records = pageInfo.getRecords();

		List<DishDto> list = records.stream().map((item)->{
			DishDto dishDto = new DishDto();

			//对象拷贝
			BeanUtils.copyProperties(item,dishDto);

			Long categoryId = item.getCategoryId();   //分类id
			//根据id查询分类对象
			Category category = categoryService.getById(categoryId);

			if(category != null){
				String categoryName = category.getName();
				dishDto.setCategoryName(categoryName);
			}
			return dishDto;
		}).collect(Collectors.toList());

		dishDtoPage.setRecords(list);

		return R.success(dishDtoPage);
	}

	/**
	 * 根据id查询菜品信息和对应的口味信息
	 * @param id
	 * @return
	 */
	@GetMapping("/{id}")
	public R<DishDto> get(@PathVariable Long id){

		DishDto dishDto = dishService.getByIdWithFlavor(id);

		return R.success(dishDto);
	}


	/**
	 * 修改菜品
	 * @param dishDto
	 * @return
	 */
	@PutMapping
	private R<String> update(@RequestBody DishDto dishDto){
		log.info(dishDto.toString());

		dishService.updateWithFlavor(dishDto);

		return R.success("新增菜品成功！");
	}

	/**
	 * 根据条件查询对应的菜品数据
	 * @param dish
	 * @return
	 */
//	@GetMapping("/list")
//	public R<List<Dish>> list(Dish dish){
//
//		//构造查询条件
//		LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
//		queryWrapper.eq(dish.getCategoryId() !=null,
//				Dish::getCategoryId,dish.getCategoryId());
//
//		//添加条件，查询状态为1的菜品
//		queryWrapper.eq(Dish::getStatus,1);
//
//		//添加排序条件
//		queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
//
//		List<Dish> list = dishService.list(queryWrapper);
//
//		return R.success(list);
//	}

	@GetMapping("/list")
	public R<List<DishDto>> list(Dish dish){

		//构造查询条件
		LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(dish.getCategoryId() !=null,
				Dish::getCategoryId,dish.getCategoryId());

		//添加条件，查询状态为1的菜品
		queryWrapper.eq(Dish::getStatus,1);

		//添加排序条件
		queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);

		List<Dish> list = dishService.list(queryWrapper);

		List<DishDto> dishDtoList = list.stream().map((item)->{
			DishDto dishDto = new DishDto();

			//对象拷贝
			BeanUtils.copyProperties(item,dishDto);

			Long categoryId = item.getCategoryId();   //分类id
			//根据id查询分类对象
			Category category = categoryService.getById(categoryId);

			if(category != null){
				String categoryName = category.getName();
				dishDto.setCategoryName(categoryName);
			}

			//当前菜品的id
			Long dishId = item.getId();
			LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
			lambdaQueryWrapper.eq(DishFlavor::getDishId,dishId);
			//SQL:select * from dish_flavor where dish_id=?
			List<DishFlavor> dishFlavorList = dishFlavorService.list(lambdaQueryWrapper);
			dishDto.setFlavors(dishFlavorList);
			return dishDto;
		}).collect(Collectors.toList());


		return R.success(dishDtoList);
	}

	/**
	 * 对菜品进行停售或者是起售
	 * @return
	 */
	@PostMapping("/status/{status}")
	public R<String> status(@PathVariable("status") Integer status,@RequestParam List<Long> ids){
//		log.info("status:{}",status);
//		log.info("ids:{}",ids);
		LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(ids != null,Dish::getId,ids);
		List<Dish> list = dishService.list(queryWrapper);

		for (Dish dish :list){
			if(dish !=null) {
				dish.setStatus(status);
				dishService.updateById(dish);
			}
		}
		return R.success("售卖状态修改成功！");
	}
	/**
	 * 菜品批量删除和单个删除
	 * 1.判断要删除的菜品在不在售卖的套餐中，如果在那不能删除
	 * 2.要先判断要删除的菜品是否在售卖，如果在售卖也不能删除
	 * @return
	 */
	//遇到一个小问题，添加菜品后，然后再添加套餐，但是套餐可选择添加的菜品选项是没有刚刚添加的菜品的？
	//原因：redis存储的数据没有过期，不知道为什么redis没有重新刷新缓存
	// （与DishController中的@GetMapping("/list")中的缓存设置有关，目前不知道咋配置刷新缓存。。。。。
	// 解决方案，把redis中的数据手动的重新加载一遍，或者是等待缓存过期后再添加相关的套餐，或者改造成使用spring catch
	@DeleteMapping
	public R<String> delete(@RequestParam("ids") List<Long> ids){
		//根据菜品id在stemeal_dish表中查出哪些套餐包含该菜品
		LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
		setmealDishLambdaQueryWrapper.in(SetmealDish::getDishId,ids);
		List<SetmealDish> SetmealDishList = setmealDishService.list(setmealDishLambdaQueryWrapper);
		//如果菜品没有关联套餐，直接删除就行  其实下面这个逻辑可以抽离出来，这里我就不抽离了
		if (SetmealDishList.size() == 0){
			//这个deleteByIds中已经做了菜品起售不能删除的判断力
			dishService.deleteByIds(ids);
			LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.in(DishFlavor::getDishId,ids);
			dishFlavorService.remove(queryWrapper);
			return R.success("菜品删除成功");
		}

		//如果菜品有关联套餐，并且该套餐正在售卖，那么不能删除
		//得到与删除菜品关联的套餐id
		ArrayList<Long> Setmeal_idList = new ArrayList<>();
		for (SetmealDish setmealDish : SetmealDishList) {
			Long setmealId = setmealDish.getSetmealId();
			Setmeal_idList.add(setmealId);
		}
		//查询出与删除菜品相关联的套餐
		LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
		setmealLambdaQueryWrapper.in(Setmeal::getId,Setmeal_idList);
		List<Setmeal> setmealList = setmealService.list(setmealLambdaQueryWrapper);
		//对拿到的所有套餐进行遍历，然后拿到套餐的售卖状态，如果有套餐正在售卖那么删除失败
		for (Setmeal setmeal : setmealList) {
			Integer status = setmeal.getStatus();
			if (status == 1){
				return R.error("删除的菜品中有关联在售套餐,删除失败！");
			}
		}

		//要删除的菜品关联的套餐没有在售，可以删除
		//这下面的代码并不一定会执行,因为如果前面的for循环中出现status == 1,那么下面的代码就不会再执行
		dishService.deleteByIds(ids);
		LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(DishFlavor::getDishId,ids);
		dishFlavorService.remove(queryWrapper);
		return R.success("菜品删除成功");
	}
}
